/*!
    \copyright  Copyright (c) 2022 - 2025 Qualcomm Technologies International, Ltd.
                All Rights Reserved.
                Qualcomm Technologies International, Ltd. Confidential and Proprietary.
    \file
    \ingroup    handset_service
    \brief
*/

#include "handset_service_advertising.h"

#include "handset_service_acceptor_list.h"
#include "handset_service_protected.h"
#include "handset_service_config.h"
#include "handset_service_sm.h"
#include "handset_service.h"

#ifdef ENABLE_LE_CONNECTION_BARGE_IN

static inline bool handsetService_IsConnectableAdvertisingAllowed(void)
{
    /*  If max LE-ACLs are not reached, we should allow (normal)connectable advertising.
     *  If truncated advertisements are configured also, we should allow the advertising.
     *  Note that truncated advertisements will be getting configured if max LE ACLs are reached
     *  or if maximum handsets are connected (i.e, consolidated handset count)
     */
    return (HandsetService_IsBleConnectable() &&
            (!HandsetServiceSm_MaxLeAclConnectionsReached() ||
            (HandsetService_IsConnectionBargeInEnabled() && LeAdvertisingManager_IsTruncatedModeEnabled())));
}

/*! \brief Check if we should enable truncated adverts or not. */
static bool handsetService_ShouldEnableTruncatedAdverts(void)
{
    /* a) If connection barge in is not enabled, we should not enable truncated advertisement.
       b) If connection barge in is enabled, we should enable truncated advertisement
           a) if maximum LE connections are reached or
           b) if maximum handset connections are reached
     */
    return (HandsetService_IsConnectionBargeInEnabled() &&
            (HandsetServiceSm_IsMaxHandsetOrMaxLeAclLimitReached()));
}

/*! \brief Enable or disable truncated advertisement based on the present condition */
static void handsetService_ConfigureTruncatedAdverts(void)
{
    bool enable_truncated_advert = handsetService_ShouldEnableTruncatedAdverts();

    /* Enable truncated mode if it is not yet enabled. */
    if (enable_truncated_advert)
    {
        if (!LeAdvertisingManager_IsTruncatedModeEnabled())
        {
            /* Truncated mode is not enabled Queue in a timer for enabling truncated adverts after guard period */
            HandsetService_RestartLeBargeInEnableTimer(HANDSET_SERVICE_PROFILE_CONNECTION_GUARD_PERIOD_MS);
        }
    }
    else
    {
        MessageCancelAll(HandsetService_GetTask(), HANDSET_SERVICE_INTERNAL_TRUNCATED_ADVERT_ENABLE);

        /* Truncated advertisement no longer allowed. So disable the mode here. */
        if (LeAdvertisingManager_IsTruncatedModeEnabled())
        {
            LeAdvertisingManager_EnableTruncatedMode(HandsetService_GetTask(), FALSE);
        }
    }
}

#else

static inline bool handsetService_IsConnectableAdvertisingAllowed(void)
{
    return (HandsetService_IsBleConnectable()
            && (HandsetServiceSm_GetLeAclConnectionCount() < handsetService_LeAclMaxConnections()));
}
#endif /* ENABLE_LE_CONNECTION_BARGE_IN */

bool HandsetService_UpdateAdvertising(void)
{
    bool advert_allowed = handsetService_IsConnectableAdvertisingAllowed();

    if (advert_allowed)
    {
#ifdef ENABLE_LEA_TARGETED_ANNOUNCEMENT
        if (!MessagePendingFirst(HandsetService_GetTask(), HANDSET_SERVICE_INTERNAL_DIRECTED_ADVERT_TIMEOUT, NULL))
        {
            LeaAdvertisingPolicy_SetAdvertisingMode(lea_adv_policy_mode_undirected,
                                                    lea_adv_policy_announcement_type_none,
                                                    lea_adv_policy_announcement_type_general,
                                                    NULL);
        }
#endif
    }

    if (HandsetService_ConsolidatedHandsetCountEnabled())
    {
        unsigned acceptor_list_count = handsetService_AcceptorListGetHandsetCount();

        if (acceptor_list_count >= handsetService_GetMaxConsolidatedHandsetConnections())
        {
            LeAdvertisingManager_SetDefaultAdvertisingFilterPolicy(LEAM_ADV_FILTER_POLICY_ALLOW_CONN_AND_SCAN_RESP_REQ_FROM_FILTER_ACCEPT_LIST_ONLY);

            DEBUG_LOG_VERBOSE("HandsetService_UpdateAdvertising enable LE filter accept list");
        }
        else
        {
            LeAdvertisingManager_SetDefaultAdvertisingFilterPolicy(LEAM_ADV_FILTER_POLICY_ALLOW_CONN_REQ_AND_SCAN_RESP_REQ_FROM_ALL);

            DEBUG_LOG_VERBOSE("HandsetService_UpdateAdvertising disable LE filter accept list");
        }

    }

#ifdef ENABLE_LE_CONNECTION_BARGE_IN
    /* Connection Barge in is enabled. Check whether the truncated adverts has to be configured or not */
    handsetService_ConfigureTruncatedAdverts();
#endif /* ENABLE_LE_CONNECTION_BARGE_IN */

    return LeAdvertisingManager_EnableConnectableAdvertising(HandsetService_GetTask(), advert_allowed);
}

#ifdef ENABLE_LE_CONNECTION_BARGE_IN

void HandsetService_DisableTruncatedAdvertising(void)
{
    MessageCancelAll(HandsetService_GetTask(), HANDSET_SERVICE_INTERNAL_TRUNCATED_ADVERT_ENABLE);
    LeAdvertisingManager_EnableConnectableAdvertising(HandsetService_GetTask(), FALSE);
    LeAdvertisingManager_EnableTruncatedMode(HandsetService_GetTask(), FALSE);
}

void HandsetService_RestartLeBargeInEnableTimer(uint32 delay)
{
    HS_LOG("HandsetService_RestartLeBargeInEnableTimer");

    /* Queue in a message to enable truncated connectable advertisement */
    MessageCancelAll(HandsetService_GetTask(), HANDSET_SERVICE_INTERNAL_TRUNCATED_ADVERT_ENABLE);
    MessageSendLater(HandsetService_GetTask(), HANDSET_SERVICE_INTERNAL_TRUNCATED_ADVERT_ENABLE, NULL, delay);
}

void HandsetService_HandleInternalTruncatedAdvertEnable(void)
{
    HS_LOG("HandsetService_HandleInternalTruncatedAdvertEnable");

    /* Handle the internal truncated mode enable message here. Ensure conditions for enabling
     * truncated mode is still present. */
    if (HandsetServiceSm_IsMaxHandsetOrMaxLeAclLimitReached())
    {
        /* Clear barge in address if it is not already cleared. */
        BdaddrTpSetEmpty(&HandsetService_Get()->barge_in_address);

        /* Start connectable advertisement in truncated mode */
        LeaAdvertisingPolicy_SetAdvertisingMode(lea_adv_policy_mode_undirected,
                                                lea_adv_policy_announcement_type_none,
                                                lea_adv_policy_announcement_type_general,
                                                NULL);

        LeAdvertisingManager_EnableTruncatedMode(HandsetService_GetTask(), TRUE);
        LeAdvertisingManager_EnableConnectableAdvertising(HandsetService_GetTask(), TRUE);
    }
}

#endif /* ENABLE_LE_CONNECTION_BARGE_IN */
